package br.com.aerusc.gui.panel;

import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;

import br.com.aerusc.entity.Jogador;
import br.com.aerusc.entity.Mensalidade;
import br.com.aerusc.enumerators.EnumMes;
import br.com.aerusc.filters.FiltroJogador;
import br.com.aerusc.filters.FiltroMensalidade;
import br.com.aerusc.gui.components.RootComponents;
import br.com.aerusc.persistence.dao.JogadorDAO;
import br.com.aerusc.persistence.dao.MensalidadeDAO;

import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Select;
import com.vaadin.ui.Table;
import com.vaadin.ui.TableFieldFactory;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;

public class PanelMensalidadeJogadores extends Panel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static final String COMMON_FIELD_WIDTH = "16em";
	private static final Logger log = Logger.getLogger(PanelMensalidadeJogadores.class.getName());
	private Table tableJogadores = new Table("Jogadores");
	private TextField fieldNome;
	private Select select;
	private GridLayout gridLayout;
	private BeanContainer<Long, Jogador> beansJogador;
	private BeanContainer<Long, Mensalidade> beansMensalidade;
	private Button buttonFiltrar;
	private Button buttonSelecionarAno;
	private Button buttonSalvar;
	private Button buttonVoltar;
	private List<Mensalidade> mensalidades;
	private Table tableMensalidades = new Table("Mensalidades");
	private Jogador jogador;
	private Window windowInformacoes;

	public PanelMensalidadeJogadores() {
		gridLayout = new GridLayout(2, 2);
		Label labelNome = new Label("Nome :");
		labelNome.setWidth(COMMON_FIELD_WIDTH);
		fieldNome = new TextField();
		fieldNome.setImmediate(true);
		fieldNome.focus();
		fieldNome.setWidth(COMMON_FIELD_WIDTH);
		gridLayout.addComponent(labelNome);
		gridLayout.addComponent(fieldNome);
		addComponent(gridLayout);
		addComponent(GetButtonFiltrar());
		addComponent(getTableJogadores());
	}

	public BeanContainer<Long, Jogador> getBeansJogador() {
		beansJogador = new BeanContainer<Long, Jogador>(Jogador.class);
		beansJogador.setBeanIdProperty("id");
		return beansJogador;
	}

	public BeanContainer<Long, Mensalidade> getBeansMensalidade() {
		beansMensalidade = new BeanContainer<Long, Mensalidade>(Mensalidade.class);
		beansMensalidade.setBeanIdProperty("id");
		return beansMensalidade;
	}

	public Table getTableJogadores() {
		tableJogadores.setContainerDataSource(getBeansJogador());
		tableJogadores.setWidth("100%");
		tableJogadores.setSelectable(true);
		tableJogadores.setImmediate(true);
		tableJogadores.setVisibleColumns(new String[] { "nome", "email", "numeroCarteira", "telefone" });
		tableJogadores.setColumnHeaders(new String[] { "Nome", "email", "Numero Carteira", "Telefone" });
		tableJogadores.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				try {
					Long id = (Long) tableJogadores.getValue();
					JogadorDAO dao = new JogadorDAO();
					Jogador jogadorBanco = dao.recuperar(id);
					jogador = jogadorBanco;
					fieldNome.setValue(jogador.getNome());
					fieldNome.setEnabled(false);
					removeComponent(buttonFiltrar);
					removeComponent(tableJogadores);
					Label labelAno = new Label("Ano  :");
					labelAno.setWidth(COMMON_FIELD_WIDTH);
					select = new Select();
					Calendar cal = Calendar.getInstance();
					for(int aux = 0;aux<4;aux++){
						Integer ano = cal.get(Calendar.YEAR) + aux -1;
						select.addItem(ano);
						select.setItemCaption(ano, ano.toString());
					}
					select.setValue(cal.get(Calendar.YEAR));
					gridLayout.addComponent(labelAno);
					gridLayout.addComponent(select);
					HorizontalLayout horizontalLayout = new HorizontalLayout();
					horizontalLayout.addComponent(getButtonSelecionarAno());
					horizontalLayout.addComponent(getButtonVoltar());
					addComponent(horizontalLayout);
				} catch (Exception e) {
					e.printStackTrace();
					log.warning(e.getMessage());
					return;
				}
			}
		});
		return tableJogadores;
	}

	public Table getTableMensalidades() {
		tableMensalidades.setContainerDataSource(getBeansMensalidade());
		tableMensalidades.setWidth("100%");
		tableMensalidades.setImmediate(true);
		tableMensalidades.setEditable(true);
		tableMensalidades.setTableFieldFactory(new MensalidadeJogadorFieldFactory());
		tableMensalidades.setVisibleColumns(new String[] { "situacao", "mes", "ano", "valor" });
		tableMensalidades.setColumnWidth("ano", 100);
		tableMensalidades.setColumnHeaders(new String[] { "Paga", "Mês", "Ano", "Valor" });
		tableMensalidades.setHeight("385px");
		return tableMensalidades;
	}

	public Button GetButtonFiltrar() {
		buttonFiltrar = new Button("Filtrar", new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				FiltroJogador filtro = new FiltroJogador();
				filtro.setNome(((String) fieldNome.getValue()).trim());
				JogadorDAO dao = new JogadorDAO();
				beansJogador = getBeansJogador();
				beansJogador.addAll(dao.listarPorFiltro(filtro));
				tableJogadores.setContainerDataSource(beansJogador);
				tableJogadores.setVisibleColumns(new String[] { "nome", "email", "numeroCarteira", "telefone" });
				tableJogadores.setColumnHeaders(new String[] { "Nome", "email", "Numero Carteira", "Telefone" });
			}
		});
		buttonFiltrar.setClickShortcut(KeyCode.ENTER);
		return buttonFiltrar;
	}
	
	public Button getButtonSelecionarAno() {
		buttonSelecionarAno = new Button("Selecionar", new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				if(buttonSalvar != null){
					removeComponent(buttonSalvar);
				}
				Integer ano = (Integer) select.getValue();
				MensalidadeDAO mensalidadeDao = new MensalidadeDAO();
				FiltroMensalidade filtro = new FiltroMensalidade();
				filtro.setIdUsuario(jogador.getId());
				filtro.setAno(ano);
				mensalidades = mensalidadeDao.listarPorFiltro(filtro);
				if (mensalidades.isEmpty()) {
					for (EnumMes mes : EnumMes.values()) {
						Mensalidade mensalidade = new Mensalidade();
						mensalidade.setAno(ano);
						mensalidade.setIdUsuario(jogador.getId());
						mensalidade.setMes(mes.getCodigo());
						mensalidade.setSituacao(false);
						mensalidades.add(mensalidade);
					}
					mensalidadeDao.salvarLista(mensalidades);
				}
				beansMensalidade = getBeansMensalidade();
				beansMensalidade.addAll(mensalidades);
				tableMensalidades.setEditable(true);
				tableMensalidades.setContainerDataSource(beansMensalidade);
				tableMensalidades.setVisibleColumns(new String[] { "situacao", "mes", "ano", "valor" });
				tableMensalidades.setColumnHeaders(new String[] { "Paga", "Mês", "Ano", "Valor" });
				tableMensalidades.setTableFieldFactory(new MensalidadeJogadorFieldFactory());
				tableMensalidades.setColumnWidth("ano", 100);
				tableMensalidades.setHeight("385px");
				addComponent(tableMensalidades);
				addComponent(getButtonSalvar());
			}
		});
		buttonSelecionarAno.focus();
		buttonSelecionarAno.setClickShortcut(KeyCode.ENTER);
		return buttonSelecionarAno;
	}
	
	public Button getButtonSalvar() {
		buttonSalvar = new Button("Salvar", new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				MensalidadeDAO mensalidadeDao = new MensalidadeDAO();
				mensalidadeDao.salvarLista(mensalidades);
				removeComponent(tableMensalidades);
				removeComponent(buttonSalvar);
				RootComponents.getMainWindow().addWindow(getWindowInformacoes("Mensalidades Salvas com Sucesso!"));
			}
		});
		buttonSalvar.setClickShortcut(KeyCode.ENTER);
		return buttonSalvar;
	}
	
	public Button getButtonVoltar() {
		buttonVoltar = new Button("Voltar", new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				RootComponents.getHorizontalSplitLayout().setSecondComponent(new PanelMensalidadeJogadores());
			}
		});
		return buttonVoltar;
	}

	private class MensalidadeJogadorFieldFactory extends DefaultFieldFactory implements TableFieldFactory {

		private static final String COMMON_FIELD_WIDTH = "16em";

		public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) {
			Field f = new TextField();
			f.setWidth(COMMON_FIELD_WIDTH);
			if ("situacao".equals(propertyId)) {
				CheckBox tf = new CheckBox();
				f = tf;
			} else if ("mes".equals(propertyId)) {
				Select select = new Select("Mês");
				for (EnumMes enumerator : EnumMes.values()) {
					select.addItem(enumerator.getCodigo());
					select.setItemCaption(enumerator.getCodigo(), enumerator.getDescricao());
				}
				select.setEnabled(false);
				f = select;
			} else if ("ano".equals(propertyId)) {
				TextField tf = (TextField) f;
				tf.setEnabled(false);
			} else if ("valor".equals(propertyId)) {
				TextField tf = (TextField) f;
			}
			if (f instanceof TextField) {
				TextField tf = (TextField) f;
				tf.setNullRepresentation("");
			}

			return f;
		}
	}
	
	public Window getWindowInformacoes(String label) {
		windowInformacoes = new Window("Sucesso");
		windowInformacoes.addComponent(new Label(label));
		windowInformacoes.setWidth("200px");
		windowInformacoes.setHeight("100px");
		windowInformacoes.setModal(true);
		windowInformacoes.setClosable(false);
		Button buttonConfirmar = new Button("Confirmar", new Button.ClickListener() {

			@Override
			public void buttonClick(ClickEvent event) {
				try {
					windowInformacoes.setVisible(false);
					windowInformacoes.detach();
					RootComponents.getHorizontalSplitLayout().setSecondComponent(new PanelMensalidadeJogadores());
				} catch (Exception e) {
					log.warning(e.getMessage());
					return;
				}
			}

		});
		buttonConfirmar.setClickShortcut(KeyCode.ENTER);
		windowInformacoes.addComponent(buttonConfirmar);

		return windowInformacoes;
	}

}
